package component;

import org.fife.ui.autocomplete.*;
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
import ui.HomePage;
import util.FileUtils;

import javax.swing.*;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
import javax.swing.text.BadLocationException;
import javax.swing.text.Caret;
import java.awt.*;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.io.File;

/**
 * @author zhongwen
 * @description 编制Java源程序的文本框
 * @date 2021-12-22 16:22
 */
public class JavaTextArea extends RSyntaxTextArea {
    private ClassTab classTab;
    public JavaTextArea(ClassTab classTab){
        this.classTab = classTab;
        this.setSyntaxEditingStyle(SYNTAX_STYLE_JAVA);
        // 括号匹配时是否显示动画
        this.setAnimateBracketMatching(false);
        // 括号匹配时应显示的颜色
        this.setMatchedBracketBGColor(new Color(135,198,199));
        this.setMatchedBracketBorderColor(new Color(135,198,199));
        // 显示相匹配的两个括号
        this.setPaintMatchedBracketPair(true);
        // 设置当前行的背景高亮色
        this.setCurrentLineHighlightColor(new Color(231,229,218));
        this.setSelectionColor(new Color(152,192,233));
        // 设置代码可折叠
        this.setCodeFoldingEnabled(true);
        CompletionProvider cmop = createCompletionProvider();
        AutoCompletion autoCompletion = new AutoCompletion(cmop);
        autoCompletion.setTriggerKey(KeyStroke.getKeyStroke(KeyEvent.VK_A, InputEvent.CTRL_MASK));
        autoCompletion.setAutoActivationEnabled(true);
        autoCompletion.install(this);
        autoCompletion.setAutoActivationEnabled(true);
        autoCompletion.setShowDescWindow(true);
        this.addCaretListener(new CaretListener() {
            @Override
            public void caretUpdate(CaretEvent e) {
                int offset = e.getDot();
                try {
                    int row = JavaTextArea.this.getLineOfOffset(offset);
                    int column = e.getDot() - JavaTextArea.this.getLineStartOffset(row);
                    BottomBar.rowAndColumnButton.setText((row + 1) + ":" + (column + 1));
                } catch (BadLocationException ex) {
                    ex.printStackTrace();
                }
            }
        });

        this.addFocusListener(new FocusAdapter() {
            @Override
            public void focusGained(FocusEvent e) {
                super.focusGained(e);
                Caret caret = JavaTextArea.this.getCaret();
                // 代码编辑界面每次获得聚焦时，在底部栏显示实时的行与列
                int offset = caret.getDot();
                try {
                    int row = JavaTextArea.this.getLineOfOffset(offset);
                    int column = caret.getDot() - JavaTextArea.this.getLineStartOffset(row);
                    BottomBar.rowAndColumnButton.setText((row + 1) + ":" + (column + 1));
                } catch (BadLocationException ex) {
                    ex.printStackTrace();
                }
                File textFile = classTab.getTextFile();
                if(textFile == null){
                    BottomBar.encodeButton.setText("UTF-8");
                }
                else{
                    HomePage.jf.setTitle("CodeEasy-" + "\"" + textFile.getAbsolutePath() + "\"");
                    String fileEncode = FileUtils.getFileEncode(textFile);
                    BottomBar.encodeButton.setText(fileEncode);
                }
            }
        });
    }

    private CompletionProvider createCompletionProvider() {

        DefaultCompletionProvider provider = new DefaultCompletionProvider();

        // 添加Java所有关键字的自动补全
        provider.addCompletion(new BasicCompletion(provider, "public"));
        provider.addCompletion(new BasicCompletion(provider, "private"));
        provider.addCompletion(new BasicCompletion(provider, "protected"));

        provider.addCompletion(new BasicCompletion(provider, "class"));
        provider.addCompletion(new BasicCompletion(provider, "interface"));
        provider.addCompletion(new BasicCompletion(provider, "abstract"));
        provider.addCompletion(new BasicCompletion(provider, "implements"));
        provider.addCompletion(new BasicCompletion(provider, "extends"));
        provider.addCompletion(new BasicCompletion(provider, "new"));

        provider.addCompletion(new BasicCompletion(provider, "import"));
        provider.addCompletion(new BasicCompletion(provider, "package"));

        provider.addCompletion(new BasicCompletion(provider, "byte"));
        provider.addCompletion(new BasicCompletion(provider, "char"));
        provider.addCompletion(new BasicCompletion(provider, "boolean"));
        provider.addCompletion(new BasicCompletion(provider, "short"));
        provider.addCompletion(new BasicCompletion(provider, "int"));
        provider.addCompletion(new BasicCompletion(provider, "float"));
        provider.addCompletion(new BasicCompletion(provider, "long"));
        provider.addCompletion(new BasicCompletion(provider, "double"));
        provider.addCompletion(new BasicCompletion(provider, "void"));
        provider.addCompletion(new BasicCompletion(provider, "null"));
        provider.addCompletion(new BasicCompletion(provider, "true"));
        provider.addCompletion(new BasicCompletion(provider, "false"));

        provider.addCompletion(new BasicCompletion(provider, "if"));
        provider.addCompletion(new BasicCompletion(provider, "else"));
        provider.addCompletion(new BasicCompletion(provider, "while"));
        provider.addCompletion(new BasicCompletion(provider, "for"));
        provider.addCompletion(new BasicCompletion(provider, "switch"));
        provider.addCompletion(new BasicCompletion(provider, "case"));
        provider.addCompletion(new BasicCompletion(provider, "default"));
        provider.addCompletion(new BasicCompletion(provider, "do"));
        provider.addCompletion(new BasicCompletion(provider, "break"));
        provider.addCompletion(new BasicCompletion(provider, "continue"));
        provider.addCompletion(new BasicCompletion(provider, "return"));
        provider.addCompletion(new BasicCompletion(provider, "instanceof"));

        provider.addCompletion(new BasicCompletion(provider, "static"));
        provider.addCompletion(new BasicCompletion(provider, "final"));
        provider.addCompletion(new BasicCompletion(provider, "super"));
        provider.addCompletion(new BasicCompletion(provider, "this"));
        provider.addCompletion(new BasicCompletion(provider, "native"));
        provider.addCompletion(new BasicCompletion(provider, "strictfp"));
        provider.addCompletion(new BasicCompletion(provider, "synchronized"));
        provider.addCompletion(new BasicCompletion(provider, "transient"));
        provider.addCompletion(new BasicCompletion(provider, "volatile"));

        provider.addCompletion(new BasicCompletion(provider, "catch"));
        provider.addCompletion(new BasicCompletion(provider, "try"));
        provider.addCompletion(new BasicCompletion(provider, "finally"));
        provider.addCompletion(new BasicCompletion(provider, "throw"));
        provider.addCompletion(new BasicCompletion(provider, "throws"));
        provider.addCompletion(new BasicCompletion(provider, "enum"));
        provider.addCompletion(new BasicCompletion(provider, "assert"));


        provider.addCompletion(new ShorthandCompletion(provider, "sout",
                "System.out.println();", "Print a string to System.out"));
        provider.addCompletion(new ShorthandCompletion(provider, "syserr",
                "System.err.println(", "System.err.println("));
        provider.addCompletion(new ShorthandCompletion(provider,"main","public static void main (" +
                "String[] args){" + "\n" + "}","静态main方法"));

        provider.addCompletion(new BasicCompletion(provider,"for(int i = 0; i <  ; i++)","for循环"));
        return provider;

    }
}
